<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        h2 {
            margin: 20px auto 0;
            text-align: center;
            color: #555;
        }
        svg {
            position: absolute;
            top: 50%;
            left: 50%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
        }
        .xaxis path,
        .xaxis line,
        .yaxis path,
        .yaxis line {
            stroke: #aaa;
            fill: none;
            shape-rendering: crispEdges;
        }
        .xaxis text,
        .yaxis text {
            font-family: sans-serif;
            font-size: 11px;
            fill: #aaa;
        }
        .datapoint {
            cursor: pointer;
            stroke: rgba(0, 0, 0, 0.2);
            fill: rgba(0, 0, 0, 0.75);
            stroke-width: 8;
        }
        .lineChart {
            fill: none;
            stroke-width: 4px;
            stroke: rgba(255, 0, 0, 0.1);
        }
    </style>
</head>
<body>
<h2>Drag datapoints to re-render chart</h2>

<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js'></script>
</body>
</html>
<script>
    var w = 800,
            h = 400,
            padding = 25;

    var dataset = [
        [10, 10],
        [20, 50],
        [30, 40],
        [40, 80],
        [50, 90],
        [60, 50],
        [70, 70],
        [80, 60],
        [90, 10],
        [100, 50],
        [110, 40],
        [120, 70],
        [130, 20],
        [140, 40],
        [150, 30]
    ];

    /*create svg element*/
    var svg = d3.select('body')
            .append('svg')
            .attr('width', w)
            .attr('height', h)
            .attr('id', 'chart');

    var drag = d3.behavior.drag()
            .on("dragstart", dragstarted)
            .on("drag", dragged)
            .on("dragend", dragended);

    /*x scale*/
    var xScale = d3.scale.linear()
            .domain([0, d3.max(dataset, function(d) {
                return d[0];
            })])
            .range([padding, w - padding]);

    /*y scale*/
    var yScale = d3.scale.linear()
            .domain([0, d3.max(dataset, function(d) {
                return d[1];
            })])
            .range([h - padding, padding]);

    /*x axis*/
    var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient('bottom');

    /*append x axis*/
    svg.append('g')
            .attr({
                'class': 'xaxis',
                'transform': 'translate(0,' + (h - padding) + ')'
            })
            .call(xAxis);

    /*y axis*/
    var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient('left');

    /*append y axis*/
    svg.append('g')
            .attr({
                'class': 'yaxis',
                'transform': 'translate(' + padding + ',0)'
            })
            .call(yAxis);

    /*define line*/
    var lines = d3.svg.line()
            .x(function(d) {
                return xScale(d[0])
            })
            .y(function(d) {
                return yScale(d[1])
            })
            .interpolate('monotone');

    /*append line*/
    var path = svg.append('path')
            .attr({
                'd': lines(dataset),
                'class': 'lineChart'
            });

    /*add points*/
    var points = svg.selectAll('circle')
            .data(dataset)
            .enter()
            .append('circle')
            .call(drag);

    /*point attributes*/
    points.attr({
        'cx': function(d) {
            return xScale(d[0]);
        },
        'cy': function(d) {
            return yScale(d[1]);
        },
        'r': 3,
        'class': 'datapoint',
        'id': function(d, i) {
            return i;
        }
    });

    var xMax = d3.max(dataset, function(d) {
                return d[0];
            }),
            yMax = d3.max(dataset, function(d) {
                return d[1];
            });

    function dragstarted() {
        d3.event.sourceEvent.stopPropagation();
        d3.select(this).classed("dragging datapoint", true);
    }

    function dragged() {
        d3.select(this)
                .attr({
                    'cx': Math.max(padding, Math.min(d3.event.x, w - padding)),
                    'cy': Math.max(padding, Math.min(d3.event.y, h - padding))
                });
    }

    function dragended() {
        d3.select(this).classed("datapoint", true);
        var id = d3.select(this).attr('id'),
                xPos = d3.select(this).attr('cx'),
                yPos = h - d3.select(this).attr('cy');

        // console.log(xMax + ' ' + yMax);
        // console.log((xPos - padding) + ' ' + (yPos - padding));
        xPos = (xPos - padding) * (xMax / (w - (padding * 2)));
        yPos = (yPos - padding) * (yMax / (h - (padding * 2)));
        dataset[id][0] = xPos;
        dataset[id][1] = yPos;
        // console.log(dataset[id]);

        var lines = d3.svg.line()
                .x(function(d) {
                    return xScale(d[0])
                })
                .y(function(d) {
                    return yScale(d[1])
                })
                .interpolate('monotone');

        svg.select('.lineChart')
                .transition()
                .duration(500)
                .attr('d', lines(dataset));
    }
</script>